#!/usr/bin/perl
###############################################
# Скрипт для автоматической генерации
# отчета за период (неделю, месяц и т.д.)
# по сгенерированному в формате HTML отчету
# "Продвижение задач за период".
# -----------  Использование -----------------
# 1. Настроить скрипт:
#     1.1 Задать корневую директорию для отчетов.
#          В этой директории ищется файл report.htm,
#          служащий источником данных.
#          В эту же директорию записывается отчет за 
#          период, сгенерированный скриптом.
#     1.2 Задать фамилию сотрудника. 
#          Фамилия используется для поиска заголовка 
#          таблицы.
#     2. Запустить отчет CBOSS "Продвижение задач
#         за период".В поле "Протокол" должно быть
#         указано "Нет".
#     3. Запустить данный скрипт. Будет сгенериован
#        и открыт текстовый файл с отчетом.
################################################

use strict;
# ------------  Настройка --------------------
# Корневая директория для отчетов:
my $reportsDir = 'C:/CBOSS/softpro30/tmp';
# Фамилия сотрудника. (Используется для поиска заголовка таблицы.)
my $lastName = 'Лосев';

use HTML::TreeBuilder;
my ($min,$hour,$mday,$mon,$year);
my $root = HTML::TreeBuilder->new_from_file("$reportsDir/report.htm");
$root = $root->elementify();
my @tables = $root->look_down(_tag => "table" ); 

my $totalHeadSum  = "";
my $totalHeadWork = "";

my $SNAME       = "SectionName";
my $TNUMS       = "TaskNumbers";
my $TNAMES      = "TaskNames";
my $SDEFAULT    = "DefaultSection";


my $TNUM        = "TaskNumber";
my $TNAME       = "TaskName";
my $TPERS1      = "Persent1";
my $TPERS2      = "Persent2";
my $TTIME       = "Time";
my $TRECS       = "ProtocolRecords";


my @Sections = 
( 
    {
        $SNAME      => "СЛУЖЕБНЫЕ БИБЛИОТЕКИ",
        $TNUMS       => [ 1001593, 1955035, 1102435, 1002454 ],
        $TNAMES   => []
    }, 
    {
        $SNAME      => "ПОДСИСТЕМА ПЕЧАТИ СЧЕТОВ",
        $TNUMS       => [],
        $TNAMES   => [],
        $SDEFAULT => 1
    }, 
    {
        $SNAME      => "ПЕРИОДИЧЕСКИЕ ЗАДАНИЯ",
        $TNUMS       => [ 1890502 ],
        $TNAMES   => [ "Коммуникации", "Обеспечение индивидуальной работы", "Регламентные работы"]
    } 
);

my %Report = ();

# Task number, Task name
# Возвращает индекс секции
sub GetSectionIndex($$)
{ 
    my $TaskNumber = shift;
    my $TaskName = shift;
    #print "GetSection: $TaskNumber, $TaskName\n";
    my $SectionIndex;
    my $DefaultSectionIndex;
    #print "keys: ", keys %{$Sections}, "\n";
    for ( $SectionIndex = 0; $SectionIndex <= $#Sections; ++$SectionIndex)
    {
        #print "--$SectionIndex--\n";
        my $ReportSection = $Sections[$SectionIndex];
        my $Elem;
        for $Elem ( @{${$ReportSection}{$TNUMS}})
        { 
             #print "Comparing:\n\t$TaskNumber\n\t$Elem\n";
            return  $SectionIndex if $TaskNumber == $Elem;
            #print "(Not equal)\n";
        }
        
        for $Elem ( @{${$ReportSection}{$TNAMES}})
        { 
             #print "Comparing:\n\t$TaskName\n\t$Elem\n";
            return  $SectionIndex if 0 == ("$TaskName" cmp "$Elem");
            #print "(Not equal)\n";
        }
        if ( exists ${$ReportSection}{$SDEFAULT} && ${$ReportSection}{$SDEFAULT})
        {        
            $DefaultSectionIndex = $SectionIndex;
        }
    }
    # Секция по умолчанию
    die "No section found, no default section specified.\n" unless defined $DefaultSectionIndex;
    return $DefaultSectionIndex;
}
sub CreateTaskInfo(\@)
{
    my $cols = shift;
    return 
    {
        $TNUM   =>  ${$cols}[1]->as_text(), 
        $TNAME  =>  ${$cols}[3]->as_text(), 
        $TPERS1    =>  ${$cols}[11]->as_text(),
        $TPERS2    =>  ${$cols}[13]->as_text(),
        $TTIME  =>  ${$cols}[15]->as_text()
    };
}
# Parameter is section index
sub AddReportSection($)
{
    my $SectionIndex = shift;
    #my $SectionInfo = $Sections[$SectionIndex];
    #my $SectionName = ${$SectionInfo}{$SNAME};
    $Report{$SectionIndex} = {} if not exists $Report{$SectionIndex};
    return $Report{$SectionIndex};
}

sub AddTaskInfo(\@)
{ 
    my $cols = shift;
    my $TaskInfo = CreateTaskInfo( @{$cols});
    my $SectionIndex = &GetSectionIndex( ${$TaskInfo}{$TNUM}, ${$TaskInfo}{$TNAME});
    my $ReportSection = AddReportSection( $SectionIndex);
    die "Duplicated task ${$TaskInfo}{$TNUM}\n" if exists ${$ReportSection}{${$TaskInfo}{$TNUM}};
    ${$ReportSection}{${$TaskInfo}{$TNUM}} = $TaskInfo;
    return $TaskInfo;    
}
sub AddProtocolRecord(\%\@)
{ 
    my $TaskInfo = shift;
    my $cols = shift;
    ${$TaskInfo}{$TRECS} = [] unless exists ${$TaskInfo}{$TRECS};
    push @{${$TaskInfo}{$TRECS}}, ${$cols}[2]->as_text();
}
for my $table ( @tables )
{
    my @rows=$table->content_list();
    my $TaskInfo;
    
    for my $row (@rows)
    {
        my @cols = $row->look_down(_tag => "td" );
        if ($#cols >= 14 && $cols[1]->as_text() =~ /[0-9]{6}/)
        {
            $TaskInfo = AddTaskInfo(@cols);
            
        }
        elsif ($#cols >= 7)
        {
            if ( $cols[1]->as_text() =~ /$lastName/ )
            {
                $totalHeadSum  = $cols[5]->as_text();
                $totalHeadWork = $cols[3]->as_text();
            }
        }
        elsif ($#cols == 2 && defined $TaskInfo)
        { 
            AddProtocolRecord( %{$TaskInfo}, @cols);        
        }
    }
}

my @ReportSections = sort keys %Report;

my $SectionIndex;
my $totalSum = 0.0;
my $SectionNumber = 1;

(undef,$min,$hour,$mday,$mon,$year,undef,undef,undef) = localtime;
$year += 1900;
$mon += 1;
my $outputName=sprintf "$reportsDir/report_%04d_%02d_%02d_%02d_%02d.txt", $year, $mon, $mday, $hour, $min;
open OUTPUT, ">"."$outputName" or die "Невозможно открыть файл $outputName. Системная ошибка: $!\n";

for $SectionIndex ( @ReportSections )
{
    my $SectionName = ${$Sections[$SectionIndex]}{$SNAME};
    print OUTPUT "$SectionNumber. $SectionName\n";
    my @ReportTaskNums = keys %{$Report{$SectionIndex}};
    my $ReportTaskNum;
    my $sectionSum = 0.0;
    
    my $TaskNumber = 1;
    for $ReportTaskNum ( @ReportTaskNums )
    {
        my $TaskInfo = ${$Report{$SectionIndex}}{$ReportTaskNum};
        printf OUTPUT "\t%s.%s %s %s\n\t\t%s-%s%% %sч.\n",
                $SectionNumber,
                $TaskNumber,
                ${$TaskInfo}{$TNUM},
                ${$TaskInfo}{$TNAME},
                ${$TaskInfo}{$TPERS1},
                ${$TaskInfo}{$TPERS2},
                ${$TaskInfo}{$TTIME},
                
        $totalSum += ${$TaskInfo}{$TTIME};
        $sectionSum += ${$TaskInfo}{$TTIME};
        if ( exists ${$TaskInfo}{$TRECS})
        {
            ; #
        }
        $TaskNumber++;
    }
    print OUTPUT "\t"."---------------------------\n\tИтого: ${sectionSum}ч.\n";
    $SectionNumber++;
}
print OUTPUT "/", "*"x90, "/\n";
print OUTPUT "Итого по задачам, вошедшим в отчет: \n", $totalSum, "ч.\n";
printf OUTPUT "Отработанное время:\n%sч.\n",$totalHeadWork;
printf OUTPUT "Итого по всем задачам (включая не вошедшие в отчет):\n%sч.\n",$totalHeadSum;
close OUTPUT;

`start $outputName`;

